package name.williamwall.buxoid;
/**
 * This software is made available under the Gnu General Public License v3
 * and has absolutely no waranty. You may change the software to suit your needs.
 * 
 * Author: William Wall, IV
 */
import java.text.NumberFormat;
import java.util.ArrayList;

import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo;

public class TransactionList extends ListActivity {
	// menu ids
	private static final int ADD_ID = Menu.FIRST;
	private static final int EDIT_ID = Menu.FIRST + 1;
	private static final int DELETE_ID = Menu.FIRST + 2;
	private static final int HELP_ID = Menu.FIRST + 3;
	private static final int UPDATE_ID = Menu.FIRST + 4;
	private static final int SETTINGS_ID = Menu.FIRST + 5;
	private static final int FILTER_TAG_ID = Menu.FIRST + 6;
	private static final int FILTER_ACCT_ID = Menu.FIRST + 7;
	
	private NumberFormat mMoneyFormat = NumberFormat.getCurrencyInstance();
	private final static String[] MONTHS = new String [] {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
	private String mAccountBuxId;
	private double mBalance;
	private int mBalanceType;
	private String mAccountName;
	private Button mMonthButton;
	private long mContextSelectedId;
	private ArrayList<String> mTags;
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle state) {
        super.onCreate(state);
        setContentView(R.layout.list_trans);
    	
        Button prev = (Button) findViewById(R.id.list_trans_prev);
        mMonthButton = (Button) findViewById(R.id.list_trans_month);
        Button next = (Button) findViewById(R.id.list_trans_next);
        
        mMoneyFormat.setCurrency(Buxoid.mDb.getCurrency());
        
        prev.setOnClickListener(new View.OnClickListener () {
			public void onClick(View view) {
				Buxoid.prevMonth();
				fillData();
			}
		});
		
		next.setOnClickListener(new View.OnClickListener() {
			public void onClick(View view) {
				Buxoid.nextMonth();
				fillData();
			}
		});
		
		mMonthButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View view) {
				new DatePickerDialog(TransactionList.this, mDateSetListener, Buxoid.mYear, Buxoid.mMonth, 1).show();
			}
		});
		
		registerForContextMenu(getListView());
    }
    
    @Override
	protected void onResume() {
		super.onResume();
		fillData();
	}
    
    private void fillData() {
        try {
    //    	Log.d("Buxfer", "filling transaction data");
        	Cursor c;
        	String [] from;
        	int [] to;
        	
        	if (Buxoid.mViewAccountId > 0) {
        		// get the account information
                c = Buxoid.mDb.fetchAccount(Buxoid.mViewAccountId);
            	//startManagingCursor(c);
            	c.moveToFirst();
            	
            	// get buxfer account id
            	mAccountBuxId = c.getString(c.getColumnIndexOrThrow(BuxoidDb.ACCOUNT_BUXID));
            	mAccountName = c.getString(c.getColumnIndex(BuxoidDb.ACCOUNT_NAME));
            	
            	// set balance
            	mBalance = c.getDouble(c.getColumnIndexOrThrow(BuxoidDb.ACCOUNT_BALANCE));
            	mBalanceType = Integer.parseInt(Buxoid.mDb.getSetting(BuxoidDb.SETTING_BALANCE_TYPE));
            	
            	// set title
            	if (mBalanceType > 0) {
    	    		// include pending transactions in balance
    	        	setTitle("Buxoid: " + mAccountName + " " + mMoneyFormat.format(mBalance + Buxoid.mDb.getPendingBalance(mAccountBuxId)));
    	    	} else {
    	    		setTitle("Buxoid: " + mAccountName + " " + mMoneyFormat.format(mBalance));
    	    	}
            	
            	// get all of the transactions for this account
    	    	c = Buxoid.mDb.fetchAllTransactionsForMonth(mAccountBuxId, Buxoid.mMonth+1, Buxoid.mYear,  Buxoid.mViewTag);
        	} else {
        		setTitle("Buxoid: Transactions");
        		
        		c = Buxoid.mDb.fetchAllTransactionsForMonth(null, Buxoid.mMonth+1, Buxoid.mYear, Buxoid.mViewTag);
        	}
    	    	
        	//startManagingCursor(c);
    
        	from = new String[] {
        			BuxoidDb.TRANS_DATE,
        			BuxoidDb.TRANS_DESC,
        			BuxoidDb.TRANS_AMOUNT,
        			BuxoidDb.TRANS_TAGS
        	};
        	
        	to = new int[] {
        			R.id.row_trans_date,
        			R.id.row_trans_desc,
        			R.id.row_trans_amount,
        			R.id.row_trans_tags
        	};
    	    	
        	// set the list adapter
    		TransactionAdapter adapter = new TransactionAdapter(this, R.layout.row_trans, c, from, to);
    		setListAdapter(adapter);
        	
        	// set month button text
    		mMonthButton.setText(MONTHS[Buxoid.mMonth] + " " + Buxoid.mYear);
        } catch (IllegalStateException e) {
            // this happens when the user starts an update and navigates away from the app
            // so just ignore it
        }
    }

	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        MenuItem item;
        
		item = menu.add(0, ADD_ID, 1, R.string.menu_add);
		item.setIcon(android.R.drawable.ic_menu_add);
		
		item = menu.add(0, FILTER_ACCT_ID, 2, R.string.menu_filter_account);
		item.setIcon(R.drawable.accounts_on);
		
		item = menu.add(0, FILTER_TAG_ID, 3, R.string.menu_filter_tag);
		item.setIcon(android.R.drawable.ic_menu_my_calendar);
		
		// set update menu item and icon
        item = menu.add(1, UPDATE_ID, 4, R.string.menu_update);
        item.setIcon(android.R.drawable.ic_menu_set_as);
        
        // set settings menu item and icon
        item = menu.add(1, SETTINGS_ID, 5, R.string.menu_settings);
        item.setIcon(android.R.drawable.ic_menu_preferences);
        
        // set help menu item and icon
        item = menu.add(1, HELP_ID, 6, R.string.menu_help);
        item.setIcon(android.R.drawable.ic_menu_help);
		
        return true;
    }
	
	

	@Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
    	Intent i;
    	int position;
    	AlertDialog.Builder adb;
    	
        switch(item.getItemId()) {
        case ADD_ID:
        	i = new Intent(this, EditTransaction.class);
        	i.putExtra(BuxoidDb.TRANS_ACCOUNTID, mAccountBuxId);
        	startActivity(i);
            return true;
        case FILTER_TAG_ID:
            Cursor t = Buxoid.mDb.fetchAllTags();
            startManagingCursor(t);
            
            mTags = new ArrayList<String>();
            mTags.add("All");
            
            position = 0;
            
            // create array for use by ArrayAdapter
            if (t.getCount() > 0 && t.moveToFirst()) {
                do {
                    if (t.getString(t.getColumnIndex(BuxoidDb.TAG_NAME)).equals(Buxoid.mViewTag)) {
                        position = t.getPosition() + 1;
                    }
                    mTags.add(t.getString(t.getColumnIndex(BuxoidDb.ACCOUNT_NAME)));
                } while (t.moveToNext());
            }  else {
                // if the cursor is empty or otherwise unusable, tell the user
                Toast.makeText(this, "You have no tags defined.", Toast.LENGTH_SHORT).show();
                return true;
            }
            
            adb = new AlertDialog.Builder(this);
            adb.setTitle("Filter by Tag");
            
            adb.setSingleChoiceItems(mTags.toArray(new String[mTags.size()]), 
                    position, 
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int itemId) {
                            Buxoid.mViewTag = mTags.get(itemId); 
                            dialog.dismiss();
                            fillData();
                        }
            });
            
            adb.show();
            return true;
             
        case FILTER_ACCT_ID:
            Cursor c = Buxoid.mDb.fetchAllAccounts();
            startManagingCursor(c);
            
            ArrayList<String> accounts = new ArrayList<String>();
            accounts.add("All");
            
            position = 0;
            
            // create array for use by ArrayAdapter
            if (c.getCount() > 0 && c.moveToFirst()) {
                do {
                    if (c.getLong(c.getColumnIndex(BuxoidDb.ACCOUNT_ROWID)) == Buxoid.mViewAccountId) {
                        position = c.getPosition() + 1;
                    }
                    accounts.add(c.getString(c.getColumnIndex(BuxoidDb.ACCOUNT_NAME)));
                } while (c.moveToNext());
            }
            
            adb = new AlertDialog.Builder(this);
            adb.setTitle("Filter by Account");
            
            adb.setSingleChoiceItems(accounts.toArray(new String[accounts.size()]), 
                    position, 
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int itemId) {
                            Buxoid.mViewAccountId = itemId;
                            dialog.dismiss();
                            fillData();
                        }
            });
            
            adb.show();
            return true;
            
        case UPDATE_ID:
            Buxoid.mUICallback = new Handler();
            Buxoid.mFinish = new Runnable () {
                public void run () {
                    fillData();
                }
            };
        	Buxoid.update(this);
        	return true;
        case SETTINGS_ID:
        	i = new Intent(this, EditSettings.class);
            startActivity(i);
            return true;
        case HELP_ID:
        	i = new Intent(this, Help.class);
        	i.putExtra("topic", "Transactions");
        	this.startActivity(i);
            return true;
        }
       
        return super.onMenuItemSelected(featureId, item);
    }

	/**
	 * This method creates the context menu on a long click
	 */
	@Override
	public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
		// set context selected id
		AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo; 
		mContextSelectedId = acmi.id;
//		Log.d("Buxfer", "context menu " + mContextSelectedId);
		
		// set up context menu header
		menu.setHeaderIcon(R.drawable.context_menu);
		TextView tv = (TextView) acmi.targetView.findViewById(R.id.row_trans_desc);
		menu.setHeaderTitle(tv.getText());
		
		// set up context menu options
		MenuItem item;
		item = menu.add(0, EDIT_ID, 1, R.string.menu_edit);
		item.setIcon(android.R.drawable.ic_menu_edit);
		
		item = menu.add(0, DELETE_ID, 2, R.string.menu_delete);
		item.setIcon(android.R.drawable.ic_menu_delete);
		
		super.onCreateContextMenu(menu, v, menuInfo);
	}
	
	/**
	 * Handles the selection from the context menu (long click menu).
	 */
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		Intent i;
		
		switch (item.getItemId()) {
		case EDIT_ID:
        	if (Buxoid.mDb.transactionEditable(mContextSelectedId)) {
	        	i = new Intent(this, EditTransaction.class);
	        	i.putExtra(BuxoidDb.TRANS_ROWID, mContextSelectedId);
	        	
	        	// store the buxfer account id in the intent
	        	i.putExtra(BuxoidDb.TRANS_ACCOUNTID, mAccountBuxId);
	        	
	        	// go forth and edit
	        	startActivity(i);
        	} else {
				String msg = "You can only edit manual transactions before syncing them. This is a limitation imposed by Buxfer.com. Sorry...";
				AlertDialog.Builder adb = new AlertDialog.Builder(this);
				adb.setCancelable(true);
				adb.setMessage(msg);
				adb.setTitle("ERROR");
				adb.create().show();
			}
            return true;
        case DELETE_ID:        	
        	// if we have permission, then delete it
        	if (Buxoid.mDb.transactionEditable(mContextSelectedId)) {
        		Buxoid.mDb.deleteTransaction(mContextSelectedId);
        	} else {
        		String msg = "You can only delete transactions before syncing them. This is a limitation imposed by Buxfer.com. Sorry...";
        		AlertDialog.Builder adb = new AlertDialog.Builder(this);
				adb.setCancelable(true);
				adb.setMessage(msg);
				adb.setTitle("ERROR");
				adb.create().show();
        	}
        	
        	fillData();
        	return true;
		}
		return super.onContextItemSelected(item);
	}
	
    /**
     * If the user clicks on a transaction, then attempt to edit it.
     */
	@Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
    	
    	if (Buxoid.mDb.transactionEditable(id)) {
        	Intent i = new Intent(this, EditTransaction.class);
        	
        	// if an item was selected, store that id in the intent
        	if (id >= 0) {
        		i.putExtra(BuxoidDb.TRANS_ROWID, id);
        	}
        	
        	// store the buxfer account id in the intent
        	i.putExtra(BuxoidDb.TRANS_ACCOUNTID, mAccountBuxId);
        	
        	// go forth and edit
        	startActivity(i);
    	} else {
    		String msg = "You can only edit manual transactions before uploading them. This is a limitation imposed by Buxfer.com. Sorry...";
    		AlertDialog.Builder adb = new AlertDialog.Builder(this);
			adb.setCancelable(true);
			adb.setMessage(msg);
			adb.setTitle("ERROR");
			adb.create().show();
    	}
    }

	private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() {
        public void onDateSet(DatePicker view, int year, int month, int day) {
        	Buxoid.mYear = Math.min(year, Buxoid.mMaxYear);
        	Buxoid.mMonth = Math.min(month, Buxoid.mMaxMonth);
        	fillData();
        }
    };
}
